//
//  SimpleValidationViewController.swift
//  rxExample
//
//  Created by 刘山 on 2021/11/3.
//

import Foundation
import UIKit
import RxSwift
import RxCocoa
import SnapKit

private let minimalUsernameLength = 5
private let minimalPasswordLength = 5

class SimpleValidationViewModel {
    // 用户名是否有效
    let usernameValid: Observable<Bool>
    // 密码是否有效
    let passwordValid: Observable<Bool>
    let everythingValid: Observable<Bool>
    
    // Error: Return from initializer without initializing all stored properties
    // 这种报错需要把所有的变量都初始化。
    init(username: Observable<String>, password: Observable<String>) {
        usernameValid = username
            .map { $0.count >= minimalUsernameLength }
            .share(replay: 1, scope: .forever)
        passwordValid = password
            .map { $0.count >= minimalPasswordLength }
            .share(replay: 1, scope: .forever)
        
        everythingValid = Observable.combineLatest(usernameValid, passwordValid) { $0 && $1}.share(replay: 1, scope: .forever)
    }
}

@objc(SimpleValidationViewController)
public class SimpleValidationViewController: UIViewController {
    let disposeBag = DisposeBag()
    
    let usernameOutlet = UITextField()
    let usernameValidOutlet = UILabel()
    
    let passwordOutlet = UITextField()
    let passwordValidOutlet = UILabel()
    
    let doSomethingOutlet = UIButton()
    var viewModel: SimpleValidationViewModel!
    
    public override func viewDidLoad() {
        self.view.backgroundColor = UIColor.white
        layout()
        viewModel = SimpleValidationViewModel(username: usernameOutlet.rx.text.orEmpty.asObservable(),
                                              password: passwordOutlet.rx.text.orEmpty.asObservable())
        
        
        viewModel.usernameValid.bind(to: passwordOutlet.rx.isEnabled).disposed(by: disposeBag)
        viewModel.usernameValid.bind(to: usernameValidOutlet.rx.isHidden).disposed(by: disposeBag)
        
        viewModel.passwordValid.bind(to: passwordValidOutlet.rx.isHidden).disposed(by: disposeBag)
        
        viewModel.everythingValid.bind(to: doSomethingOutlet.rx.isEnabled).disposed(by: disposeBag)
        doSomethingOutlet.rx.tap.subscribe { [weak self] _ in
            self?.showAlert()
        }.disposed(by: disposeBag)
    }
    
    func showAlert() {
        let alert = UIAlertController(title: "RxExample", message: "This is Perfect!", preferredStyle: .alert)
        let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
        alert.addAction(defaultAction)
        present(alert, animated: true, completion: nil)
    }
    
    @objc func doSomethingOutletClick() {
        print("Can Click!")
    }
    
    func layout() {
        doSomethingOutlet.setTitle("Submit", for: .normal)
        doSomethingOutlet.backgroundColor = UIColor.blue
        doSomethingOutlet.addTarget(self, action: #selector(doSomethingOutletClick), for: .touchUpInside)
        
        self.view.addSubview(usernameOutlet)
        self.view.addSubview(usernameValidOutlet)
        self.view.addSubview(passwordOutlet)
        self.view.addSubview(passwordValidOutlet)
        self.view.addSubview(doSomethingOutlet)
        
        usernameOutlet.placeholder = "用户名："
        passwordOutlet.placeholder = "密码："
        
        usernameOutlet.borderStyle = .roundedRect
        usernameOutlet.clearButtonMode = .whileEditing
        usernameOutlet.keyboardType = .emailAddress
        usernameOutlet.returnKeyType = .done
        
        passwordOutlet.borderStyle = .roundedRect
        passwordOutlet.clearButtonMode = .whileEditing
        passwordOutlet.keyboardType = .emailAddress
        passwordOutlet.returnKeyType = .done
        
        usernameValidOutlet.text = "Username has to be at least \(minimalUsernameLength) characters"
        usernameValidOutlet.textColor = UIColor.red

        passwordValidOutlet.text = "Password has to be at least \(minimalPasswordLength) characters"
        passwordValidOutlet.textColor = UIColor.red

        usernameOutlet.snp.makeConstraints { make in
            make.left.equalTo(self.view).offset(15)
            make.right.equalTo(self.view).offset(-15)
            make.top.equalTo(self.view).offset(100)
        }
        usernameValidOutlet.snp.makeConstraints { make in
            make.left.equalTo(self.view).offset(15)
            make.right.equalTo(self.view).offset(-15)
            make.top.equalTo(usernameOutlet.snp_bottom).offset(5)
        }
        
        passwordOutlet.snp.makeConstraints { make in
            make.left.equalTo(self.view).offset(15)
            make.right.equalTo(self.view).offset(-15)
            make.top.equalTo(usernameValidOutlet.snp_bottom).offset(10)
        }
        passwordValidOutlet.snp.makeConstraints { make in
            make.left.equalTo(self.view).offset(15)
            make.right.equalTo(self.view).offset(-15)
            make.top.equalTo(passwordOutlet.snp_bottom).offset(5)
        }
        
        doSomethingOutlet.snp.makeConstraints { make in
            make.left.equalTo(self.view).offset(15)
            make.right.equalTo(self.view).offset(-15)
            make.top.equalTo(passwordValidOutlet.snp_bottom).offset(10)
        }
    }
}
